/**
 * @file calculate_score.h
 * @brief 评分计算模块头文件
 */

#ifndef CALCULATE_SCORE_H
#define CALCULATE_SCORE_H

#include "feature_extractor.h"
#include "score_engine.h"

// ---------- 评分缓冲结构体及管理接口 ----------

// 用于存储整首歌所有帧特征的缓冲区
typedef struct {
    int buffer_size;      // 缓冲区大小(= total_frames + 10)
    int total_frames;     // 歌曲总帧数
    
    float* pitch_buffer;      // 音调缓冲
    float* energy_buffer;     // 音强缓冲
    float* brightness_buffer; // 明亮度缓冲
    float* timbre_buffer;     // 音色缓冲
    float* flux_buffer;       // 频谱通量缓冲

    float* pitch_buffer_base;      // 基准音调缓冲
    float* energy_buffer_base;     // 基准音强缓冲
    float* brightness_buffer_base; // 基准明亮度缓冲
    float* timbre_buffer_base;     // 基准音色缓冲
    float* rhythm_buffer_base;     // 基准节奏缓冲
    float* vad_buffer_base;        // 基准VAD缓冲   
} ScoreFeatureBuffers;

/**
 * @brief 创建评分缓冲区
 * @param buffer_size 缓冲区大小(一般为 total_frames + 10)
 * @param total_frames 总帧数
 * @return ScoreFeatureBuffers* 成功返回指针, 失败返回 NULL
 */
ScoreFeatureBuffers* create_calculate_score_buffers(int buffer_size, int total_frames);

/**
 * @brief 释放评分缓冲区
 * @param buffers 评分缓冲区指针
 */
void free_calculate_score_buffers(ScoreFeatureBuffers* buffers);

/**
 * @brief 使用频谱通量检测句子起始点
 * @param buffers 特征缓冲区
 * @param end_frame_idx 句子结束帧索引
 * @param search_range 向前搜索的最大帧数
 * @return int 检测到的起始帧索引，如果未检测到返回-1
 */
int detect_onset_by_flux(const ScoreFeatureBuffers* buffers, int end_frame_idx, int search_range);

/**
 * @brief 使用能量法检测句子起始点
 * @param buffers 特征缓冲区
 * @param end_frame_idx 句子结束帧索引
 * @param search_range 向前搜索的最大帧数
 * @return int 检测到的起始帧索引，如果未检测到返回-1
 */
int detect_onset_by_energy(const ScoreFeatureBuffers* buffers, int end_frame_idx, int search_range);

/**
 * @brief 结合频谱通量和能量法检测句子起始点
 * @param buffers 特征缓冲区
 * @param end_frame_idx 句子结束帧索引
 * @param search_range 向前搜索的最大帧数
 * @param w1 能量法权重(0-1)
 * @param w2 频谱通量权重(0-1)
 * @return int 检测到的起始帧索引，如果未检测到返回-1
 */
int detect_onset_combined(const ScoreFeatureBuffers* buffers, int end_frame_idx, 
                         int search_range, float w1, float w2);

/**
 * @brief 通过基准文件的节奏值检测句子起始点
 * 当节奏值为1时表示句子开始
 * 
 * @param buffers 特征缓冲区
 * @param end_frame_idx 句子结束帧索引
 * @return int 检测到的起始帧索引，如果未检测到返回-1
 */
int detect_sentence_start_by_rhythm(const ScoreFeatureBuffers* buffers, int end_frame_idx);

// 音高评分配置
typedef struct {
    float tolerance;          // 音高容错度
    float dev_weight;         // 偏差权重
    float std_weight;         // 标准差权重
    float curve_factor;       // 评分曲线因子
} PitchScoreConfig;

// 节奏评分配置
typedef struct {
    float tolerance;          // 节奏容错度
    float curve_factor;       // 评分曲线因子
} RhythmScoreConfig;

// 明亮度评分配置
typedef struct {
    float tolerance;          // 明亮度容错度
    float dev_weight;         // 偏差权重
    float std_weight;         // 标准差权重
    float curve_factor;       // 评分曲线因子
} BrightnessScoreConfig;

// 气息评分配置
typedef struct {
    float energy_weight;      // 能量权重
    float hnr_weight;         // 谐波噪声比权重
    float tolerance;          // 气息容错度
    float curve_factor;       // 评分曲线因子
} BreathScoreConfig;

// 情感评分配置
typedef struct {
    float tolerance;          // 相关系数容忍度 (0~1, corr>=tol 即视为满分)
    float gamma;              // 低分段压缩指数 γ (>1 更严格)
    float curve_factor;       // 评分曲线因子
} EmotionScoreConfig;

// 音色评分配置
typedef struct {
    float tolerance;          // 音色容错度
    float dev_weight;         // 偏差权重
    float std_weight;         // 标准差权重
    float curve_factor;       // 评分曲线因子
} TimbreScoreConfig;

/**
 * @brief 从引擎配置获取评分模块所需参数配置
 * 
 * @param config 引擎配置
 * @return ScoreEngineConfig 处理后的评分配置
 */
void prepare_score_config_from_engine_config(const ScoreEngineConfig* engine_config, 
                                          PitchScoreConfig* pitch_config,
                                          RhythmScoreConfig* rhythm_config,
                                          BrightnessScoreConfig* brightness_config,
                                          BreathScoreConfig* breath_config,
                                          EmotionScoreConfig* emotion_config,
                                          TimbreScoreConfig* timbre_config);

/**
 * @brief 计算音准评分
 * 
 * @param buffers 评分缓冲区
 * @param frame_idx_start 起始帧索引
 * @param frame_idx_end 结束帧索引
 * @param config 评分配置
 * @return float 音准评分(0-1范围)
 */
float calculate_pitch_score(const ScoreFeatureBuffers* buffers, int frame_idx_start, int frame_idx_end, const PitchScoreConfig* config);

/**
 * @brief 计算节奏评分
 * 
 * @param buffers 评分缓冲区
 * @param frame_idx 帧索引
 * @param config 评分配置
 * @return float 节奏评分(0-1范围)
 */
float calculate_rhythm_score(const ScoreFeatureBuffers* buffers, int frame_idx, const RhythmScoreConfig* config);

#if RHYTHM_METHOD_CHAR
float calculate_rhythm_score_char(const ScoreFeatureBuffers* buffers, int frame_idx_end, const RhythmScoreConfig* config);
#endif

/**
 * @brief 计算明亮度评分
 * 
 * @param buffers 评分缓冲区
 * @param frame_idx_start 起始帧索引
 * @param frame_idx_end 结束帧索引
 * @param config 评分配置
 * @return float 明亮度评分(0-1范围)
 */
float calculate_brightness_score(const ScoreFeatureBuffers* buffers, int frame_idx_start, int frame_idx_end, const BrightnessScoreConfig* config);

/**
 * @brief 计算气息评分
 * 
 * @param buffers 评分缓冲区
 * @param frame_idx_start 起始帧索引
 * @param frame_idx_end 结束帧索引
 * @param config 评分配置
 * @return float 气息评分(0-1范围)
 */
float calculate_breath_score(const ScoreFeatureBuffers* buffers, int frame_idx_start, int frame_idx_end, const BreathScoreConfig* config);

/**
 * @brief 计算情感评分
 * 
 * @param buffers 评分缓冲区
 * @param frame_idx_start 起始帧索引
 * @param frame_idx_end 结束帧索引
 * @param config 评分配置
 * @return float 情感评分(0-1范围)
 */
float calculate_emotion_score(const ScoreFeatureBuffers* buffers, int frame_idx_start, int frame_idx_end, const EmotionScoreConfig* config);

/**
 * @brief 计算音色评分
 * 
 * @param buffers 评分缓冲区
 * @param frame_idx_start 起始帧索引
 * @param frame_idx_end 结束帧索引
 * @param config 评分配置
 * @return float 音色评分(0-1范围)
 */
float calculate_timbre_score(const ScoreFeatureBuffers* buffers, int frame_idx_start, int frame_idx_end, const TimbreScoreConfig* config);

/**
 * @brief 应用评分曲线
 * 
 * @param raw_score 原始评分(0-1范围)
 * @param curve_factor 曲线因子
 * @return int 最终评分(0-100范围)
 */
int apply_score_curve(float raw_score, float curve_factor);

/**
 * @brief 计算总体评分
 * 
 * @param buffers 评分缓冲区
 * @param frame_idx 帧索引
 * @param result 评分结果
 * @param engine_config 引擎配置
 * @return int 成功返回0，失败返回错误码
 */
int calculate_overall_score(const ScoreFeatureBuffers* buffers, int frame_idx,
                          ScoreResult* result, const ScoreEngineConfig* engine_config);

#endif /* CALCULATE_SCORE_H */ 